﻿using MCPlatform.MotionLib.Base;
using MCPlatform.MotionLib.Base.Models;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MCPlatform.MotionLib.Factory.LeadShine
{
    public class LTIO : IIO
    {

        private ushort _cardNo;//卡号
        private ushort _portNo;
    

        protected NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();//打印日志

        public event Action<object>? RisingEvent;
        public event Action<object>? FallingEvent;

        private bool _fistScan = false;
        private bool _tempValue = false;

        private bool _tempFlipperValue = false;
        public string IOName { get ; set; } = string.Empty;
        public string Type { get; set; } = "I";
        public ushort Address { get; set; }


        private System.Timers.Timer _timer = new System.Timers.Timer(500);

        /// <summary>
        /// 默认闪烁频率为0.5s
        /// </summary>
        public double Interval 
        {
            get { return _interval; }
            set
            {
                _interval = value;
                _timer.Interval = value;
            }
        }
        private double _interval;


        /// <summary>
        /// 闪烁
        /// </summary>
        public bool Flipper
        {
            get { return _Flipper; }
            set
            {

                if (IsShield)
                {
                    return;
                }

                if (Type.Equals("I"))
                {
                    return;
                }

                if (value)
                {
                    _timer.Start();
                }
                else
                {
                    WriteOutBitNolog(Address,1);
                    _timer.Stop();
                }
                
            }
        }

        private bool _Flipper;
        public bool Value
        {
            get
            {
                if (IsShield)
                {
                    return true;
                }

                if (Type.Equals("I"))
                {
                   bool readValue =   ReadInBit(Address) > 0 ? false:true;

                    if (!_fistScan)
                    {
                        _tempValue = readValue;
                        _fistScan = true;
                    }

                    if (readValue == _tempValue)
                    {
                        return readValue;
                    }
                    _tempValue = readValue;
                    if (_tempValue)
                    {
                        //上升沿
                        RisingEvent?.Invoke(this);
                    }
                    else
                    {
                        //下降沿
                        FallingEvent?.Invoke(this);
                    }

                    return readValue;
                }
                else if (Type.Equals("Q"))
                {
                   return ReadOutBit(Address) > 0 ? false : true;
                }
                else
                {
                    return false;
                }

            }
            set
            {
                

                if (Type.Equals("I"))
                {
                    return;
                }

                _timer.Stop();

                if (IsShield)
                {
                    return;
                }

                WriteOutBit(Address,value ? (ushort)0: (ushort)1);
            }
        }

        public bool IsShield 
        {
            get 
            { 
                return _isShield; 
            }

            set
            {
                if (_isShield != value)
                {
                    _isShield = value;
                }
                if (value)
                {
                   
                    WriteOutBit(Address, 1);
                }
                
            }
        }
        private bool _isShield;

        public int DelayTime { get; set; }

        

        public IOParaModel IOConfig
        {
            get { return _IOConfig; }
            set
            {
                _IOConfig = value;
                IsShield = value.IsShield;
                DelayTime = value.DelayTime;
            }
        }
        private IOParaModel _IOConfig = new IOParaModel();

        public LTIO()
        {
            _timer.Elapsed += _timer_Elapsed;
        }

        private void _timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            if (IsShield)
            {
                return;
            }
            _tempFlipperValue = !_tempFlipperValue;
            WriteOutBitNolog(Address, _tempFlipperValue ? (ushort)0 : (ushort)1);
        }

        /// <summary>
        /// 读单个输入点电平
        /// </summary>
        /// <param name="bitNo"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public short ReadInBit(ushort bitNo)
        {
            try
            {
                //LTDMC.dmc_set_da_enable();
                //LTDMC.dmc_set_da_output
                //logger.Info("执行： LTDMC.dmc_read_inbit");
                var res = LTDMC.dmc_read_inbit(_cardNo, bitNo);
                return LTDMC.dmc_read_inbit(_cardNo, bitNo);
            }
            catch (Exception ex)
            {

                logger.Error($"命令异常： LTDMC.dmc_read_inbit { bitNo} + {ex.Message}");
                throw new Exception("命令：" + "LTDMC.dmc_read_inbit" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }

        /// <summary>
        /// 读单个输出点电平
        /// </summary>
        /// <param name="bitNo"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public short ReadOutBit(ushort bitNo)
        {
            try
            {
                //logger.Info("执行： LTDMC.dmc_read_inbit");
                return LTDMC.dmc_read_outbit(_cardNo, bitNo);
            }
            catch (Exception ex)
            {

                logger.Error($"命令异常： LTDMC.dmc_read_outbit {bitNo} + {ex.Message}");
                throw new Exception("命令：" + "LTDMC.dmc_read_inbit" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }


        /// <summary>
        /// 写单个输出点电平
        /// </summary>
        /// <param name="bitNo"></param>
        /// <param name="onOrOff"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public short WriteOutBit(ushort bitNo, ushort onOrOff)
        {
            try
            {
                string status = onOrOff > 0 ? "关闭":"打开";
                logger.Info($"{IOName}，卡号：{_cardNo},执行： LTDMC.dmc_write_outbit: 点位：{bitNo},{status}");
                return LTDMC.dmc_write_outbit(_cardNo, bitNo, onOrOff);
            }
            catch (Exception ex)
            {

                logger.Error($"命令异常： LTDMC.dmc_write_outbit 卡号：{_cardNo},{IOName},点位： {bitNo} Status:{onOrOff} { ex.Message}");
                throw new Exception("命令：" + "LTDMC.dmc_write_outbit" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }

        public short WriteOutBitNolog(ushort bitNo, ushort onOrOff)
        {
            try
            {
                
                return LTDMC.dmc_write_outbit(_cardNo, bitNo, onOrOff);
            }
            catch (Exception ex)
            {

                logger.Error($"命令异常： LTDMC.dmc_write_outbit 卡号：{_cardNo},{IOName},点位： {bitNo} Status:{onOrOff} {ex.Message}");
                throw new Exception("命令：" + "LTDMC.dmc_write_outbit" + ex.Message + "堆栈: " + ex.StackTrace);
            }
        }
    }
}
